﻿using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.VirtualRoutes;

namespace ApplicationFrame.EntityFrameworkCore.Core
{
    /// <summary>
    /// 分表策略接口
    /// </summary>
    public interface IShardingStrategy<TEntity, TKey> where TEntity : class
    {
        /// <summary>
        /// 获取分表后缀
        /// </summary>
        string GetTail(TKey shardingKey);

        ///// <summary>
        ///// 获取数据库现在的分表后缀
        ///// </summary>
        //List<string> GetTails();

        /// <summary>
        /// 如何路由到具体表 shardingKeyValue:分表的值, 返回结果:如果返回true表示返回该表 第一个参数 tail 第二参数是否返回该物理表
        /// </summary>
        Func<string, bool> GetRouteToFilter(TKey shardingKey, ShardingOperatorEnum shardingOperator);

        /// <summary>
        /// 配置实体分表元数据（绑定分表键属性）
        /// </summary>
        void Configure(EntityMetadataTableBuilder<TEntity> builder);
    }

    public abstract class AbstractShardingStrategy<TEntity, TKey> : IShardingStrategy<TEntity, TKey> where TEntity : class
    {
        /// <summary>
        /// 分表属性名称
        /// </summary>
        protected string ShardingPropertyName { get; set; }

        public virtual void Configure(EntityMetadataTableBuilder<TEntity> builder)
        {
            builder.ShardingProperty(ShardingPropertyName);
        }

        public abstract string GetTail(TKey shardingKey);

        //public abstract List<string> GetTails();

        public abstract Func<string, bool> GetRouteToFilter(TKey shardingKey, ShardingOperatorEnum shardingOperator);
    }
}
